package com.atguigu.controller;

import com.alibaba.dubbo.config.annotation.Reference;
import com.atguigu.entity.UserInfo;
import com.atguigu.result.Result;
import com.atguigu.result.ResultCodeEnum;
import com.atguigu.service.UserInfoService;
import com.atguigu.util.MD5;
import com.atguigu.util.ValidateCodeUtils;
import com.atguigu.vo.LoginVo;
import com.atguigu.vo.RegisterVo;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/userInfo")
public class UserInfoController {
    @Reference
    private UserInfoService userInfoService;


    @RequestMapping("/sendCode/{phone}")
    public Result sendCode(@PathVariable String phone, HttpServletRequest request){
        //应该返回一个验证码给用户,然后我这边服务器端session再保存一个.然后提交登录的时候再跟输入进来的一起对比.
        //我们这里不用发短信  做一个假的直接返回给前端.
        //1.通过生成验证码工具类生成随机验证码
        String code = ValidateCodeUtils.generateValidateCode4String(6);
        //2.将验证码放入session域方便登录获取比对
        request.getSession().setAttribute("CODE",code);
        return Result.ok(code);
    }

    @RequestMapping("/register")
    public Result register(@RequestBody RegisterVo registerVo,HttpServletRequest request){
        //获取到注册需要的参数
        String nickName = registerVo.getNickName();
        String phone = registerVo.getPhone();
        String password = registerVo.getPassword();
        String code = registerVo.getCode();
        //校验参数是否合理
        if(StringUtils.isEmpty(nickName)
                || StringUtils.isEmpty(phone)
                || StringUtils.isEmpty(password)
                || StringUtils.isEmpty(code) ){
            return Result.build(null, ResultCodeEnum.PARAM_ERROR);
        }

        //校验验证码是否正确
        String codeOk=(String)request.getSession().getAttribute("CODE");
        if(!code.equals(codeOk)){
            return Result.build(null,ResultCodeEnum.CODE_ERROR);
        }
        //校验手机号是否已注册
        UserInfo userInfo=userInfoService.getByPhone(phone);
        if (userInfo!=null){
            return Result.build(null,ResultCodeEnum.PHONE_REGISTER_ERROR);
        }
        userInfo=new UserInfo();
        //调用业务层进行账户注册
        userInfo.setNickName(nickName);
        userInfo.setPassword(MD5.encrypt(password));
        userInfo.setPhone(phone);
        userInfo.setStatus(1);
        userInfoService.insert(userInfo);
        return Result.ok();
    }

    @RequestMapping("/login")
    public Result login(@RequestBody LoginVo loginVo,HttpServletRequest request){
        //获取前端穿过来的登录数据
        String phone = loginVo.getPhone();
        String password = loginVo.getPassword();
        //对数据进行非空判断校验
        if(StringUtils.isEmpty(phone)
                || StringUtils.isEmpty(password)){
            return Result.build(null, ResultCodeEnum.PARAM_ERROR);
        }
        //根据手机号进行用户查询
        UserInfo userInfo = userInfoService.getByPhone(phone);
        //进行查询后的校验(判断账户是否存在)
        if(userInfo==null){
            //查询到的数据为空,返回错误信息
            return Result.build(null,ResultCodeEnum.ACCOUNT_ERROR);
        }
        //进行密码校验
        if(!userInfo.getPassword().equals(MD5.encrypt(password))){
            return Result.build(null,ResultCodeEnum.PASSWORD_ERROR);
        }
        //账号密码都正确,登录成功,需要给前端传入必要用户数据
        //备注:还需要给登录的session域存储一份.用于记录当前这个会话的用户是谁,点关注可以在这定位用户.
        request.getSession().setAttribute("USER",userInfo);
        Map map=new HashMap<>();
        map.put("nickName",userInfo.getNickName());
        map.put("phone",phone);
        return Result.ok(map);
    }

    @RequestMapping("/logout")
    public Result logout(HttpServletRequest request){
        //清除session数据   我们登录的时候在里面放入了userInfo信息
        //request.getSession().removeAttribute("USER");    也可以这样移除存入的信息,但session id还是原来的
        //推荐直接删除session
        request.getSession().invalidate();
        return Result.ok();
    }

}
